package com.starlink.service.impl;

import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.starlink.client.ras.RasClient;
import com.starlink.client.ras.request.WrapAuditListRequest;
import com.starlink.client.ras.request.WrapRequest;
import com.starlink.client.ras.response.RasBaseResponse;
import com.starlink.client.ras.response.WrapAuditListResponse;
import com.starlink.common.PageInfoTwo;
import com.starlink.common.enums.ErrorCode;
import com.starlink.common.enums.SchoolbagTypeEnum;
import com.starlink.common.exception.BusinessException;
import com.starlink.common.utils.AssertUtil;
import com.starlink.mapper.SchoolbagMapper;
import com.starlink.model.domain.SchoolbagDO;
import com.starlink.model.domain.SchoolbagPhaseBooksDO;
import com.starlink.model.domain.SchoolbagPhaseDO;
import com.starlink.model.dtomapper.SchoolbagDtoMapper;
import com.starlink.model.request.SchoolbagPhaseBooksRequest;
import com.starlink.model.request.SchoolbagPhaseRequest;
import com.starlink.model.request.SchoolbagRequest;
import com.starlink.model.request.SchoolbagSpecificationRequest;
import com.starlink.model.util.SchoolbagConvert;
import com.starlink.model.vo.SchoolbagPhaseVO;
import com.starlink.model.vo.SchoolbagSpecificationVO;
import com.starlink.model.vo.SchoolbagVO;
import com.starlink.service.SchoolbagPhaseBooksService;
import com.starlink.service.SchoolbagPhaseService;
import com.starlink.service.SchoolbagService;
import com.starlink.service.SchoolbagSpecificationService;
import freemarker.core.BugException;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.starlink.utils.IDUtils.getId;

/**
 * @author zhanghong
 */
@Service
public class SchoolbagServiceImpl extends ServiceImpl<SchoolbagMapper, SchoolbagDO> implements SchoolbagService {
    @Autowired
    private SchoolbagMapper schoolbagMapper;
    @Autowired
    private SchoolbagPhaseService schoolbagPhaseService;
    @Autowired
    private SchoolbagPhaseBooksService schoolbagPhaseBooksService;
    @Autowired
    private RasClient rasClient;
    @Autowired
    private SchoolbagSpecificationService schoolbagSpecificationService;

    @Override
    public SchoolbagVO getByKey(long id) {
        SchoolbagVO schoolbagVO = SchoolbagDtoMapper.INSTANCE.do2VO(getById(id));
        if (schoolbagVO == null) {
            return null;
        }
        // 查询规格
        SchoolbagSpecificationRequest specificationRequest = new SchoolbagSpecificationRequest();
        specificationRequest.setSchoolbagId(schoolbagVO.getId());
        List<SchoolbagSpecificationVO> specs = schoolbagSpecificationService.listQuery(specificationRequest);
        for (SchoolbagSpecificationVO item : specs) {
            // 查询规格分期书单
            SchoolbagPhaseRequest request = new SchoolbagPhaseRequest();
            request.setCategoryId(item.getSchoolbagId());
            request.setSpecId(item.getId());
            List<SchoolbagPhaseVO> phases = schoolbagPhaseService.listQuery(request);
            for (SchoolbagPhaseVO phase : phases) {
                SchoolbagPhaseBooksRequest booksRequest = new SchoolbagPhaseBooksRequest();
                booksRequest.setCategoryId(item.getSchoolbagId());
                booksRequest.setSpecId(item.getId());
                booksRequest.setPhaseId(phase.getId());
                phase.setPhaseBooks(schoolbagPhaseBooksService.listQuery(booksRequest));
            }
            item.setPhases(phases);
            item.setPhasesBooks(phases.stream().map(SchoolbagPhaseVO::getPhaseBooks).flatMap(Collection::stream).collect(Collectors.toList()));
        }
        schoolbagVO.setSpecs(specs);
        return schoolbagVO;
    }

    @Override
    public PageInfoTwo<SchoolbagVO> pageQuery(SchoolbagRequest request) {
        long count = schoolbagMapper.pageCount(request);
        List<SchoolbagDO> list = schoolbagMapper.pageQuery(request, request.getPageSize(), request.fetchOffSet());
        List<SchoolbagVO> schoolbagVOList = SchoolbagConvert.buildSchoolbagVoList(list);
        return new PageInfoTwo(request.getPageNum(), request.getPageSize(), schoolbagVOList, count);
    }

    @Override
    public List<SchoolbagVO> listQuery(SchoolbagRequest request) {
        List<SchoolbagDO> list = schoolbagMapper.selectDOList(SchoolbagDtoMapper.INSTANCE.request2DO(request));
        List<SchoolbagVO> schoolbagVOS = SchoolbagConvert.buildSchoolbagVoList(list);
        return schoolbagVOS;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean add(SchoolbagRequest request) {
        // 校验
        if (CollectionUtils.isNotEmpty(request.getThemeLabel())) {
            AssertUtil.assertTrue(request.getThemeLabel().size() <= 10, "主题标签不能超过20个");
            AssertUtil.assertTrue(request.getThemeLabel().stream().allMatch(item -> item.length() <= 20), "主题标签不能超过20个字");
        }
        if (CollectionUtils.isNotEmpty(request.getReadGuide())) {
            AssertUtil.assertTrue(request.getReadGuide().size() <= 10, "培育阅读素养与写作能力超过10个");
            AssertUtil.assertTrue(request.getReadGuide().stream().allMatch(item -> item.length() <= 20), "培育阅读素养与写作能力不能超过20个字");
        }
        if (CollectionUtils.isNotEmpty(request.getNormalLabel())) {
            AssertUtil.assertTrue(request.getReadGuide().size() <= 10, "阅读赋能韧性与抗逆力提升超过10个");
            AssertUtil.assertTrue(request.getReadGuide().stream().allMatch(item -> item.length() <= 20), "阅读赋能韧性与抗逆力提升不能超过20个字");
        }
        SchoolbagDO schoolbagDO = SchoolbagDtoMapper.INSTANCE.request2DO(request);
        try {
            schoolbagDO.setId(getId());
            save(schoolbagDO);
        } catch (Exception ex) {
            if (ex.getMessage().contains("Data too long")) {
                throw new BusinessException(ErrorCode.PARAM_ERROR, "详情内容超长，请优化！");
            }
        }
        // 新增RAS书包
        SchoolbagTypeEnum schoolbagTypeEnum = SchoolbagTypeEnum.findByCode(request.getType());
        AssertUtil.assertNotNull(schoolbagTypeEnum, "非法的书包类型");
        WrapRequest wrapRequest = new WrapRequest();
        wrapRequest.setWrapName(schoolbagTypeEnum.getName());// 获取type名称
        wrapRequest.setMainImageOfTheWrap(request.getImages().get(0));
        wrapRequest.setWrapSpecs(String.format(wrapRequest.getWrapSpecs(), schoolbagDO.getSpecification()));
        RasBaseResponse<Integer> rasBaseResponse = rasClient.wrap(wrapRequest);
        AssertUtil.assertNotNull(rasBaseResponse.getData(), "创建RAS外包装商品失败");
        schoolbagDO.setRasId(rasBaseResponse.getData());
        this.saveOrUpdate(schoolbagDO);
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean updateByKey(SchoolbagRequest request) {
        // 校验
        if (CollectionUtils.isNotEmpty(request.getThemeLabel())) {
            AssertUtil.assertTrue(request.getThemeLabel().size() <= 10, "主题标签不能超过10个");
            AssertUtil.assertTrue(request.getThemeLabel().stream().allMatch(item -> item.length() <= 100), "主题标签不能超过100个字");
        }
        if (CollectionUtils.isNotEmpty(request.getReadGuide())) {
            AssertUtil.assertTrue(request.getReadGuide().size() <= 10, "培育阅读素养与写作能力超过10个");
            AssertUtil.assertTrue(request.getReadGuide().stream().allMatch(item -> item.length() <= 100), "培育阅读素养与写作能力不能超过100个字");
        }
        if (CollectionUtils.isNotEmpty(request.getNormalLabel())) {
            AssertUtil.assertTrue(request.getReadGuide().size() <= 10, "阅读赋能韧性与抗逆力提升超过10个");
            AssertUtil.assertTrue(request.getReadGuide().stream().allMatch(item -> item.length() <= 100), "阅读赋能韧性与抗逆力提升不能超过100个字");
        }
        AssertUtil.assertNotNull(request.getId(), "id不能为空");
        SchoolbagDO schoolbagDO = SchoolbagDtoMapper.INSTANCE.request2DO(request);
        try {
//            // 新增RAS书包
//            SchoolbagTypeEnum schoolbagTypeEnum = SchoolbagTypeEnum.findByCode(request.getType());
//            AssertUtil.assertNotNull(schoolbagTypeEnum, "非法的书包类型");
//            WrapRequest wrapRequest = new WrapRequest();
//            wrapRequest.setWrapName(String.format("%s(%s)", request.getName(), schoolbagTypeEnum.getName()));// 获取type名称
//            wrapRequest.setMainImageOfTheWrap(request.getImages().get(0));
//            wrapRequest.setWrapSpecs(String.format(wrapRequest.getWrapSpecs(), schoolbagDO.getSpecification()));
//            RasBaseResponse<Integer> rasBaseResponse = rasClient.wrap(wrapRequest);
//            AssertUtil.assertNotNull(rasBaseResponse.getData(), "创建RAS外包装商品失败");
//            schoolbagDO.setRasId(rasBaseResponse.getData());
            saveOrUpdate(schoolbagDO);
        } catch (Exception ex) {
            if (ex.getMessage().contains("Data too long")) {
                throw new BusinessException(ErrorCode.PARAM_ERROR, "详情内容超长，请优化！");
            }
        }

        return true;
    }

    /**
     * 根据主键删除
     *
     * @param ids
     * @return
     */
    @Override
    public Boolean deleteByIds(String ids) {
        schoolbagMapper.deleteDOByIds(Convert.toStrArray(ids));
        return true;
    }

    @Override
    public Boolean validAuditStatus(Long id) {
        //todo 前端传参不对
//        AssertUtil.assertNotNull(id, "书包id不能为空");
//        SchoolbagDO schoolbagDO = schoolbagMapper.selectDOById(id);
//        AssertUtil.assertNotNull(schoolbagDO, "书包不存在");
//        if (schoolbagDO.getRasId() == null) {
//            return false;
//        }
//
//        WrapAuditListRequest request = new WrapAuditListRequest();
//        request.setId(schoolbagDO.getRasId());
//        RasBaseResponse<WrapAuditListResponse> response = rasClient.wrapAuditList(request);
//        return Optional.ofNullable(response).map(RasBaseResponse::getData).map(item -> CollectionUtils.isNotEmpty(item.getRecords())).orElse(false);
        return true;
    }

}
